#pragma once

#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <atomic>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/time.h>
#include <boost/algorithm/string.hpp>

namespace ns_util{//namesapce-util，utility多用途的或工具性质的
    class TimeUtil{
        static std::string GetTimeStamp(){//
            struct timeval _time;//定义一个时间戳
            gettimeofday(&_time, nullptr);//获取当前时间，存储在 _time 结构体中，nullptr表示时区信息
            return std::to_string(_time.tv_sec);//将 _time 结构体中的秒数（tv_sec）转换为字符串
        }
        static std::string GetTimeMs(){//获得毫秒时间戳
            struct timeval _time;
            gettimeofday(&_time, nullptr);
            return std::to_string(_time.tv_sec * 1000 + _time.tv_usec / 1000);
        }
    }
}

const std::string temp_path = "./temp/";//定义一个临时路径

class PathUtil{
    public:
    static std::string AddSuffix(const std::string &file_name, const std::string &suffix){//添加后缀
        std::string path_name = temp_path;//临时路径
            path_name += file_name;
            path_name += suffix;
            return path_name;
    }
    static std::string Src(const std::string &file_name){//source源文件
        return AddSuffix(file_name, ".cpp");
    }
    static std::string Exe(const std::string &file_name){//可执行文件
        return AddSuffix(file_name, ".exe");
    }
    static std::string CompilerError(const std::string &file_name){//编辑器错误
        return AddSuffix(file_name, ".compile_error");
    }
    static std::string Stdin(const std::string &file_name){
        return AddSuffix(file_name, ".stdin");
    }
    static std::string Stdout(const std::string &file_name){
        return AddSuffix(file_name, ".stdout");
    }
    static std::string Stderr(const std::string &file_name){
        return AddSuffix(file_name, ".stderr");
    }
}

class FileUtil{
    static bool IsFileExists(const std::string &path_name){//文件是否存在
        struct stat st;//储存详细属性信息
        if (stat(path_name.c_str(), &st) == 0)//获取 path_name 指定的文件或目录的状态信息,并将结果存储在 st 中
                                      //如果操作成功（即文件存在且信息可获取），则条件为真
            {
                //获取属性成功，文件已经存在
                return true;
            }
            return false;
    }
    static std::string UniqFileName(){//唯一文件名
        static std::atomic_uint id(0);//声明一个静态的、原子性的无符号整型变量 id 并初始化为 0
        id++;
        std::string ms = TimeUtil::GetTimeMs();//获取当前时间的毫秒数作为字符串
        std::string uniq_id = std::to_string(id);//将整数id转换为字符串
        return ms + "_" + uniq_id;//将时间毫秒数和唯一标识符拼接成一个新的字符串
    }
    static bool WriteFile(const std::string &target, const std::string &content){//分别输入的是文件的目标与内容
        std::ofstream out(target);//创建（或打开）一个文件流out，用于向文件target写入数据
        if (!out.is_open())//检查文件是否成功打开
            {
                return false;
            }
            out.write(content.c_str(), content.size());//向文件中写入字符串 content 的内容，str(string)
            out.close();
            return true;
    }
    static bool ReadFile(const std::string &target, std::string *content, bool keep = false){
        (*content).clear();//清空 content 指向的对象的内容
        std::ifstream in(target);//打开文件 target 以供读取，并将文件流与 in 关联
        if (!in.is_open())
            {
                return false;
            }
        std::string line;//结合下面的程序，line是读取文件中每一行的信息
        while (std::getline(in, line))//读取文件流 in 中的一行，并将它存储到字符串 line 中
            {
                (*content) += line;
                (*content) += (keep ? "\n" : "");
            }//逐行读取文件内容，并追加到 content 指向的字符串或容器中，根据 keep 的值决定是否在每行后添加换行符
            in.close();
            return true;
    }
}
class StringUtil{
    static void SplitString(const std::string &str, std::vector<std::string> *target, const std::string &sep){//分割字符串
        /*************************************
         * str: 输入型，目标要切分的字符串
         * target: 输出型，保存切分完毕的结果
         * sep: 指定的分割符
         * **********************************/
        boost::split((*target), str, boost::is_any_of(sep), boost::algorithm::token_compress_on);
        //使用 sep 作为分隔符来分割 str 字符串，并将分割后的结果存储在 target 指向的容器中，同时去除连续的空字符串（即压缩空白）
    }
}